<style scoped lang="scss">
/deep/ .system-auditlog-dialog {
  margin-top: 5vh !important;
  max-width: 1200px;
  .basic-table {
    width: 100%;
    td {
      padding: 10px;
      border: 1px solid #dee2e6;
    }
  }
  .action-table {
    width: 100%;
    th {
      background-color: #f8f9fa;
    }
    th, td {
      padding: 10px;
      border: 1px solid #dee2e6;
    }
    .content {
      min-height: 60px;
    }
    .jv-container .jv-code {
      padding: 10px 20px;
    }
  }
}
</style>

<template>
  <div class="loginlogs_list_box">
    <div class="toolbars mrgb5">
        <div class="buttons mrgb5">
            <div class="fr">
                <el-date-picker class="c-datetime-range mrgr5 mrgb5" v-model="selectedTime" type="datetimerange" size="medium"
                    :picker-options="pickerOptions" :default-time="['00:00:00', '23:59:59']" @change="_search"
                    range-separator="至"
                    start-placeholder="开始时间"
                    end-placeholder="结束时间"
                    align="right">
                </el-date-picker>
                <el-input class="c-el-input mrgr5 mrgb5" placeholder="关键字" clearable v-model="listQuery.keywords"
                        size="medium"></el-input>
                <el-button type="primary" size="medium" @click="_search()"><i class="fa fa-search"></i> 查询</el-button>
            </div>
            <div class="clearb"></div>
        </div>
    </div>
    <el-table :data="tableData" border @row-dblclick="_query">
      <el-table-column label="操作者" prop="userName" min-width="100"></el-table-column>
      <el-table-column label="URL" prop="url" min-width="150">
        <template slot-scope="scope">
          {{ scope.row.url }}
          ({{ scope.row.httpMethod }})
        </template>
      </el-table-column>
      <el-table-column label="状态码" width="120">
        <template slot-scope="scope">
          {{ scope.row.httpStatusCode }}
          <el-tag type="danger" size="small" v-if="scope.row.exceptions">异常</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作者IP" prop="clientIpAddress" width="120"></el-table-column>
      <el-table-column label="操作时间" prop="executionTime" :formatter="tableDateFormat" min-width="100"></el-table-column>
      <el-table-column label="Tag" width="250">
        <template slot-scope="scope">{{ scope.row.extraProperties && scope.row.extraProperties.Tag }}</template>
      </el-table-column>
      <el-table-column label="操作" width="100" fixed="right">
          <template slot-scope="scope">
            <el-button type="primary" plain size="mini" @click="_query(scope.row)">详情</el-button>
          </template>
      </el-table-column>
    </el-table>

    <div class="pagination-container" v-if="isPagination">
      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" 
      :current-page="listQuery.page" :page-sizes="appPageSizes" :page-size="listQuery.size" 
      layout="total, sizes, prev, pager, next, jumper" :total="total">
      </el-pagination>
    </div>

    <el-dialog title="操作日志详情" custom-class="c-el-dialog system-auditlog-dialog" :visible.sync="showDialog" :before-close="_close" :close-on-click-modal="false">
      <table class="basic-table">
        <tr>
          <td width="100">操作者</td>
          <td>{{ dialogData.userName }}</td>
        </tr>
        <tr>
          <td>操作时间</td>
          <td>{{ getFormatDate(dialogData.executionTime) }}</td>
        </tr>
        <tr>
          <td>操作者IP</td>
          <td>{{ dialogData.clientIpAddress }}</td>
        </tr>
        <tr>
          <td>执行时长</td>
          <td>{{ dialogData.executionDuration / 1000 }}秒</td>
        </tr>
        <tr>
          <td>请求URL</td>
          <td>{{ dialogData.url }}({{ dialogData.httpMethod }})</td>
        </tr>
        <tr>
          <td>状态码</td>
          <td>
            {{ dialogData.httpStatusCode }}
            <el-tag type="danger" size="small" v-if="dialogData.exceptions">异常</el-tag>
          </td>
        </tr>
        <tr>
          <td>浏览器信息</td>
          <td>{{ dialogData.browserInfo }}</td>
        </tr>
      </table>
      <el-tabs class="mrgt20" type="border-card" v-model="activeName"
        v-if="dialogData.actions && dialogData.actions.length > 0 || dialogData.exceptions || dialogData.entityChanges && dialogData.entityChanges.length > 0">
          <el-tab-pane label="Actions数据" name="basic" v-if="dialogData.actions && dialogData.actions.length > 0">
            <table class="action-table mrgt10 mrgb10" v-for="(item, index) in dialogData.actions" :key="'action' + index">
              <tr>
                <th>服务名：{{ item.serviceName }}</th>
              </tr>
              <tr>
                <td>
                  <!--json viewer-->
                  <json-viewer :ref="'refAction' + index" :value="item" :expand-depth="5" copyable></json-viewer>
                </td>
              </tr>
            </table>
          </el-tab-pane>
          <el-tab-pane label="Exceptions异常数据" v-if="dialogData.exceptions" name="error">
            <json-viewer ref="exception" :value="dialogData.exceptions" :expand-depth="5" copyable></json-viewer>
          </el-tab-pane>
          <el-tab-pane label="Entity改变数据" v-if="dialogData.entityChanges && dialogData.entityChanges.length > 0" name="entity">
            <table class="action-table mrgt10 mrgb10" v-for="(item, index) in dialogData.entityChanges" :key="'entityChanges' + index">
              <tr>
                <th>服务名：{{ item.entityTypeFullName }}</th>
              </tr>
              <tr>
                <td>
                  <!--json viewer-->
                  <json-viewer :ref="'refEntityChanges' + index" :value="item" :expand-depth="5" copyable></json-viewer>
                </td>
              </tr>
            </table>
          </el-tab-pane>
        </el-tabs>
        <span slot="footer">
            <el-button size="small" @click="_close()">关闭</el-button>
        </span>
    </el-dialog>
  </div>
</template>

<script>
  import * as auditLogs from '@/api/system/user'
  import moment from "moment"
  import JsonViewer from 'vue-json-viewer'
  export default {
    name: "operationLogs",
    components: { JsonViewer },
    data() {
      let that = this
      return {
        tableData: [],
        total: null,
        listQuery: {
          keywords: "",
          beginDate: "",
          endDate: "",
          page: 1,
          size: window.$common.appPageSize
        },
        isPagination: false,
        showDialog: false,
        dialogData: {},
        activeName: "",
        jsonData: {},
        selectedTime: [],
        pickerOptions: {
            shortcuts: [
                {
                    text: "今天",
                    onClick: (picker) => {
                        let timeArr = that.setPickerTime(picker, 1, "days")
                        that.setQueryTime(timeArr)
                    }
                },
                {
                    text: "近一周",
                    onClick: (picker) => {
                        let timeArr = that.setPickerTime(picker, 1, "weeks")
                        that.setQueryTime(timeArr)
                    }
                },
                {
                    text: "近一月",
                    onClick(picker) {
                        let timeArr = that.setPickerTime(picker, 1, "months")
                        that.setQueryTime(timeArr)
                    }
                },
                {
                    text: "近三月",
                    onClick(picker) {
                        let timeArr = that.setPickerTime(picker, 3, "months")
                        that.setQueryTime(timeArr)
                    }
                },
                {
                    text: "近半年",
                    onClick(picker) {
                        let timeArr = that.setPickerTime(picker, 6, "months")
                        that.setQueryTime(timeArr)
                    }
                },
                {
                    text: "近一年",
                    onClick(picker) {
                        let timeArr = that.setPickerTime(picker, 1, "years")
                        that.setQueryTime(timeArr)
                    }
                }
            ]
        }
      }
    },
    mounted() {
      this.getListData()
    },
    methods: {
      setQueryTime(timeArr) {
          this.listQuery.beginDate = timeArr[0] || ""
          this.listQuery.endDate = timeArr[1] || ""
      },
      handleSizeChange(val) {
        window.$common.fullLoading()
        this.listQuery.size = val
        this.getListData()
      },
      handleCurrentChange(val) {
        window.$common.fullLoading()
        this.listQuery.page = val
        this.getListData()
      },
      setSelectedTime() {
          let psTime = ""
          let peTime = ""
          if (this.selectedTime && this.selectedTime[0] && moment(this.selectedTime[0]).isValid()) {
              psTime = moment(this.selectedTime[0]).format("YYYY-MM-DD HH:mm:ss")
          }
          if (this.selectedTime && this.selectedTime[1] && moment(this.selectedTime[1]).isValid()) {
              peTime = moment(this.selectedTime[1]).format("YYYY-MM-DD HH:mm:ss")
          }
          this.listQuery.beginDate = psTime
          this.listQuery.endDate = peTime
          this.selectedTime = [this.listQuery.beginDate, this.listQuery.endDate]
      },
      getListData() {
        this.setSelectedTime()
        window.$common.fullLoading()
        auditLogs.getAuditLogs(this.listQuery).then(response => {
          window.$common.closeFullLoading()
          this.total = response.totalCount
          this.isPagination = response.totalCount > 0 || false
          if (response && response.items && response.items.length > 0) {
            this.tableData = response.items.map(item => {
              let names = item.actions.map(x => {
                return x.serviceName
              })
              item.serviceName = names.join("<br />")
              return item
            })
          } else {
            this.tableData = []
          }
        })
      },
      _query(row) {
        this.dialogData = row
        // 转换actions
        try {
          this.dialogData.actions = this.dialogData.actions && this.dialogData.actions.map(x => {
            x.parameters = x.parameters && JSON.parse(x.parameters)
            x.executionTime = this.getFormatDate(x.executionTime)
            return x
          }) || []
        } catch(e) {
          console.error("转换actions存在异常!")
        }
        // 转换exceptions
        try {
          this.dialogData.exceptions = this.dialogData.exceptions && JSON.parse(this.dialogData.exceptions)
        } catch(e) {
          console.error("转换exceptions存在异常!")
        }
        // 转换entityChanges
        try {
          this.dialogData.entityChanges = this.dialogData.entityChanges && this.dialogData.entityChanges.map(x => {
            x.changeTime = this.getFormatDate(x.changeTime)
            return x
          }) || []
        } catch(e) {
          console.error("转换entityChanges存在异常!")
        }
        this.activeName = "basic"
        this.showDialog = true
      },
      _search() {
        this.listQuery.page = 1
        this.getListData()
      },
      _close() {
        this.showDialog = false
      }
    }
  }
</script>